package com.ikas.ai.server.module.flow.listener;

import com.ikas.ai.framework.core.event.FlowEvent;
import com.ikas.ai.framework.core.listener.FlowListener;
import com.ikas.ai.framework.flow.FlowStatus;
import com.ikas.ai.framework.flow.ScoreFlow;
import com.ikas.ai.framework.node.ChainNode;
import com.ikas.ai.framework.node.Node;
import com.ikas.ai.framework.node.impl.EndNode;
import com.ikas.ai.server.module.AssessModelTaskService;
import com.ikas.ai.server.module.assessment.model.vo.TaskCallBackNodeInfoVo;
import com.ikas.ai.server.module.assessment.model.vo.TaskCallBackServiceVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Description: 评分监听器
 *
 * @Author: qi.yilai
 * @Date: 2023/2/7 14:54
 * @Version: 1.0.0
 **/
@Component
@Slf4j
public class AssessWfResultListener implements FlowListener {

    @Autowired
    @Lazy
    private AssessModelTaskService assessModelTaskService;

    @Override
    public boolean fireEvent(FlowEvent event) {
        ScoreFlow scoreFlow = event.getOwner();
        FlowStatus flowStatus = scoreFlow.getStatus();

        if (flowStatus == FlowStatus.SUCCESS || flowStatus == FlowStatus.FAILURE || flowStatus == FlowStatus.STOP) {
            List<ChainNode> nodes =  scoreFlow.getNodes();
            handlerNodesResult(scoreFlow, nodes);
            return true;
        } else {
            return false;
        }
    }

    private void handlerNodesResult(ScoreFlow scoreFlow, List<ChainNode> nodes) {
        TaskCallBackServiceVo taskCallBackServiceVo = new TaskCallBackServiceVo();
        taskCallBackServiceVo.setSceneName(scoreFlow.getSceneName());
        taskCallBackServiceVo.setSceneId(scoreFlow.getSceneId());
        taskCallBackServiceVo.setFlowId(scoreFlow.getFlowId());
        taskCallBackServiceVo.setFlowInstanceId(scoreFlow.getFlowInstanceId());
        taskCallBackServiceVo.setFlowStatus(scoreFlow.getStatus().getStatus());

        List<Node> ends = nodes.stream().filter(node -> node.getCurrentNode() instanceof EndNode).map(ChainNode::getCurrentNode).collect(Collectors.toList());
        List<TaskCallBackNodeInfoVo> list = ends.stream()
                .filter(end -> ((EndNode) end).isSuccess())
                .map(end -> {
            EndNode endNode = (EndNode) end;
            TaskCallBackNodeInfoVo taskCallBackNodeServiceVo = new TaskCallBackNodeInfoVo();
            taskCallBackNodeServiceVo.setRiskName(endNode.getRiskName());
            taskCallBackNodeServiceVo.setDisStrategy(endNode.getStrategy());
            taskCallBackNodeServiceVo.setNodeId(endNode.nodeId());
            taskCallBackNodeServiceVo.setNodeInstanceId(endNode.nodeInstanceId());
            taskCallBackNodeServiceVo.setFailRate(Objects.toString(endNode.getRestartProb()));
            taskCallBackNodeServiceVo.setOccurProb(Objects.toString(endNode.getHappenProb()));
            taskCallBackNodeServiceVo.setEndNodeStatus(endNode.status().getStatus());
            return taskCallBackNodeServiceVo;

        }).collect(Collectors.toList());

        taskCallBackServiceVo.setNodeList(list);
        assessModelTaskService.flowExecCallBack(taskCallBackServiceVo);
    }
}
